package com.mtzqc.common.service.impl

import android.os.Parcelable
import com.blankj.utilcode.util.StringUtils
import com.didi.drouter.annotation.Service
import com.didi.drouter.api.Extend
import com.mtzqc.common.kt.loadService
import com.mtzqc.common.manager.JsonManager
import com.mtzqc.common.service.JsonService
import com.mtzqc.common.service.KvService
import com.tencent.mmkv.MMKV

@Service(function = [KvService::class], cache = Extend.Cache.SINGLETON)
class KvImpl : KvService {

    private val kv: MMKV by lazy {
        MMKV.defaultMMKV()
    }

    override fun put(key: String, value: Any): Boolean {
        return when (value) {
            is Int -> kv.encode(key, value)
            is Long -> kv.encode(key, value)
            is Double -> kv.encode(key, value)
            is Float -> kv.encode(key, value)
            is Boolean -> kv.encode(key, value)
            is String -> kv.encode(key, value)
            is Parcelable -> kv.encode(key, value)
            is ByteArray -> kv.encode(key, value)
            is Set<*> -> kv.encode(key, value as Set<String>)
            else -> put(key, JsonManager.toJson(value)!!)
        }
    }

    override fun containsKey(key: String): Boolean {
        return kv.containsKey(key)
    }

    override fun remove(key: String) {
        kv.remove(key)
    }

    override fun <T> get(key: String, clazz: Class<T>): T? {
        var value: Any? = if (Boolean::class.java.isAssignableFrom(clazz)) {
            kv.decodeBool(key)
        } else if (String::class.java.isAssignableFrom(clazz)) {
            kv.decodeString(key)
        } else if (Int::class.java.isAssignableFrom(clazz)) {
            kv.decodeInt(key)
        } else if (Long::class.java.isAssignableFrom(clazz)) {
            kv.decodeLong(key)
        } else if (Double::class.java.isAssignableFrom(clazz)) {
            kv.decodeDouble(key)
        } else if (Double::class.java.isAssignableFrom(clazz)) {
            kv.decodeDouble(key)
        } else if (Float::class.java.isAssignableFrom(clazz)) {
            kv.decodeFloat(key)
        } else if (Parcelable::class.java.isAssignableFrom(clazz)) {
            kv.decodeParcelable(key, clazz as Class<Parcelable>)
        } else if (Set::class.java.isAssignableFrom(clazz)) {
            kv.decodeStringSet(key)
        } else {
            get(key, String::class.java)?.let {
                JsonManager.fromJson(it, clazz)
            }
        }
        return value as? T
    }

}